ZK Elements
This documentation is for an older version of ZK. For the latest one, please click here.
Helper component that's not UI. It helps to save variable, write java code in ZUML, and others.
zk
|
Aggregate other components |
zscript
|
Write java code in ZUML |
attribute ]
|
Make the page more readable |
variables
|
Store variable in namespace scope |
custom-attributes
|
Store variables in different scopes |
Overview
ZK elements are used to control ZUML pages other than creating components.
The zk
Element
<zk>...</zk>
It is a special element used to aggregate other components. Unlike a real component (say, hbox
or div
), it is not part of the component tree being created. In other words, it doesn't represent any component. For example,
<window>
<zk>
<textbox/>
<textbox/>
</zk>
</window>
is equivalent to
<window>
<textbox/>
<textbox/>
</window>
Then, what is it used for?
Multiple Root Elements in a Page
Due to XML's syntax limitation, we can only specify one document root. Thus, if you have multiple root components, you must use zk
as the document root to group these root components.[1]
<?page title="Multiple Root"?>
<zk>
<window title="First">
...
</window>
<window title="Second">
...
</window>
</zk>
Iteration Over Versatile Components
The zk
element, like components, supports the forEach
attribute. Thus, you could use it to generate different type of components depending on the conditions. In the following example, we assume mycols
is a collection of objects that have member, isUseText()
. For each object in mycols
, a textbox
will be created if isUseText() returns true. useText
is auto transformed to isUseText()
by EL expression evaluation.
<window>
<zk forEach="${mycols}">
<textbox if="${each.useText}"/>
</zk>
</window>
For more information about forEach
, if
, please refer to section The ZK Attributes.
Notes
- ↑ A component without any parent is called a root component
The zscript
Element
Write java code in ZUML
<zscript>Scripting codes</zscript> <zscript src="uri"/>
It defines a piece of the scripting codes, say the Java codes, that will be interpreted when the page is evaluated. The language of the scripting codes is, by default, Java.
The zscript
element has two formats as shown above. The first format is used to embed the scripting codes directly in the page. The second format is used to reference an external file that contains the scripting codes.
You can also embed zscript
in event handler in ZUML. In the following example,
<button onClick="alert("Hi")"/>
alert("quot;Hi"quot;)
is also a piece of zscript
code.
src | [Optional][Default: none]
Specifies the URI of the file containing the scripting codes. If specified, the scripting codes will be loaded as if they are embedded directly.
|
deferred | [Optional][Default: false ]
Whether to defer the evaluation of this element until the first non-deferred |
How to Defer the Evaluation
ZK loads the interpreter before it is going to evaluate the first zscript
codes. For example, the Java interpreter is loaded when the user clicks the button in the following example.
<button onClick="alert("Hi")"/>
On the other hand, the interpreter is loaded when loading the following ZUML page, since the zscript
element needs to be evaluated when loading the page.
<window>
<zscript>
void add() {
}
</zscript>
<button onClick="add()"/>
</window>
If you prefer to defer the loading of the interpreter, you can specify the deferred
option with true. Then, the interpreter won't be loaded, until the user clicks the button.
<window>
<zscript deferred="true">
void add() {
}
</zscript>
<button onClick="add()"/>
</window>
Note: The evaluation of EL expressions specified in the if
, unless
and src
attributes are also deferred.
Note: If the component is detached from the page by the time the interpreter is loaded, the zscript
codes are ignored. For example, if the window in the previous example no longer belongs to the page, the deferred zscript
won't be interpreted.
The attribute
Element
Make the page more readable
It defines a XML attribute of the enclosing element. The content of the element is the attribute value, while the name
attribute specifies the attribute name. It is useful if the value of an attribute is sophisticated, or the attribute is conditional. With proper use, it makes the page more readable.
For example:
<button label="Say Hello" onClick="alert("Hello World!")"/>
is equivalent to
<button label="Say Hello">
<attribute name="onClick">alert("Hello World!");</attribute>
</button>
In the following example, title of the window depends on ${new}
.
<window>
<attribute name="title" if="${new}">New is True</attribute>
</window>
Native Content
In addition, you can specify a XML fragment as the value of the attribute. The XML fragment is so-called the native content.
<html>
<attribute name="content">
<ol>
<li forEach="${values}">${each}</li>
</ol>
</attribute>
</html>
where ol
and li
are part of the native content. They are not ZK components. They will be eventually converted to a String instance and assigned to the specified attribute. If values has three elements, the above example is equivalent to the following:
<html>
<attribute name="content">
<ol>
<li>${values[0]}</li>
<li>${values[1]}</li>
<li>${values[2]}</li>
</ol>
</attribute>
</html>
name | [Required]
Specifies the attribute name. |
trim | [Optional][Default: false]
Specifies whether to omit the leading and trailing white-spaces of the attribute value. |
The custom-attributes
element
The custom-attributes
element is used to defines a set of custom attributes. Custom attributes are objects associated with a particular scope. Acceptable scopes include component, ID space, page, desktop, session and application.
As depicted below, custom-attributes
is convenient to assign custom attributes without programming.
<window>
<custom-attributes main.rich="simple" very-simple="intuitive"/>
</window>
It is equivalent to
<window>
<zscript>
self.setAttribute("main.rich", "simple");
self.setAttribute("very-simple", "intuitive");
</zscript>
</window>
Moreover, you could specify what scope to assign the custom attributes to.
<window id="main" title="Welcome">
<custom-attributes scope="desktop" shared="${main.title}"/>
</window>
It is equivalent to
<window id="main">
<zscript>
desktop.setAttribute("shared", main.title);
</zscript>
</window>
Retrieve attributes directly in EL and zscript
Since ZK 5.0, the custom attribute can be accessed directly if its name is a valid Java name. For example,
<window>
<custom-attributes less="is more"/>
${less}
<zscript>
if ("is more".equals(less)) { //true
}
</zscript>
</window>
ZK will look up the value of a custom attribute from the nearest component, to its parent, to its ancestor, to its page, to its desktop, to the session, and to the application, until found.
Retrieve attributes in EL via built-in variables
A custom attribute can be retrieved from one of the following built-in variables, componentScope
, spaceScope
, pageScope
, desktopScope
, sessionScope
, and applicationScope
. They are all maps representing different scopes.
${pageScope.something}
Notice that EL expression is evaluated against the component being created. Sometime it is subtle to notice. For example, ${componentScope.simple}
is evaluated to null
, in the following codes. Why? It is a shortcut of <label value="${componentScope.simple}"/>
. In other words, the component, self
, is the label rather than the window, when the EL is evaluated.
<window>
<custom-attributes simple="intuitive"/>
${componentScope.simple}
</window>
is equivalent to
<window>
<custom-attributes simple="intuitive"/>
<label value="${componentScope.simple}"/><!-- self is label not window -->
</window>
Tip: Don't confuse <attribute>
with <custom-attributes>
. They are irrelevant. The attribute
element is a way to assign value to a predefined XML attribute of the enclosing element, while the custom-attributes
element is used to assign new custom attributes to particular scopes.
Specify a list or a map of values with the composite
Attribute
If you want to specify a list of values, you can specify the composite
attribute with list
as follows.
<custom-attributes simple="apple, orange" composite="list"/>
Then, it is converted to a list with two elements. The first element is "apple" and the second "orange".
If you want to specify a map of values, you can specify the composite
attribute with map
as follows.
<custom-attributes simple="juice=apple, flavor=orange" composite="map"/>
Then, it is converted to a map with two entries. The first entry is ("juice", "apple") and the second ("flavor", "orange").
Specify null
In the following example, var
is an empty string.
<custom-attributes var=""/>
To define a variable with the null value, use the following statement.
<custom-attributes var="${null}"/>
scope | [Optional][Default: component]
Specifies what scope to associate the custom attributes to. |
composite | [Optional][Default: none ]
Specifies the format of the value. It could be |
The variables
element
[deprecated since 5.0] The concept of namespace (and variables) is deprecated and replaced with the custom attribute (#The custom-attributes element).
The variables
element is used to define a set of variables in the namespace. It is equivalent to the setVariable
method of Component
.
A namespace is a unique scope that is associated with an ID space. The relation is one-to-one. However, it is deprecated since ZK 5.0 (because of the redundancy with custom attributes).
As depicted below, variables
is convenient to assign variables without programming.
In the following example, we set a variable named "rich", and its value is "simple", a variable named "simple" and its value is "intuitive".
<window>
<variables rich="simple" simple="intuitive"/>
</window>
It is equivalent to
<window>
<zscript>
self.setVariable("rich", "simple", false);
self.setVariable("simple", "intuitive", false);
</zscript>
</window>
Of course, you can specify EL expressions for the values.
<window id="win1">
<window id="w" title="Test">
<variables title="${w.title}"/>
1: ${title}
</window>
2: ${title}
</window>
The result will show 1: Test 2:
. Since title
is invisible in win1
. Because it is stored in namespace, and window
is an id space, and therefore a namespace.
Like Component
's setVariable
, you can control whether to declare variables local to the current ID space as follows. If not specified, local="false"
is assumed.
<variables simple="rich" local="true"/>
Note: local is an attribute of variables
, so it's not parsed as a variable name. By default, local
is false. It means if parent namespace has same variable, its value will be changed too.
In the following example, you can change the value of local
to see the difference.
<window>
<variables title="def"/>
<window title="Test">
<variables title="abc" local="false" />
1: ${title}
</window>
2: ${title}
</window>
Specify a list or a map of values with the composite
Attribute
If you want to specify a list of values, you can specify the composite
attribute with list
as follows.
<variables simple="apple, orange" composite="list"/>
Then, it is converted to a list with two elements. The first element is "apple" and the second "orange".
If you want to specify a map of values, you can specify the composite
attribute with map
as follows.
<variables simple="juice=apple, flavor=orange" composite="map"/>
Then, it is converted to a map with two entries. The first entry is ("juice", "apple") and the second ("flavor", "orange").
Specify null
In the following example, var
is an empty string.
<variables var=""/>
To define a variable with the null value, use the following statement.
<variables var="${null}"/>
See Also
From ZK Forum
Quiz
- What's root component? How many root component can a page have?
- Where does
setVariable
store variable? - Where does
custom-attributes
store variable?